package com.start.workflow.core.listener;

import com.start.common.entity.StartBaseUser;
import com.start.common.std.StartBaseSingleton;
import com.start.common.std.StartSingletonFactory;
import com.start.common.tools.SpringContextTools;
import com.start.workflow.common.enums.StartActUserTaskConf;
import com.start.workflow.core.dispatcher.StartGlobalActTaskEventDispatcher;
import com.start.workflow.core.manage.StartActCandidateManager;
import com.start.workflow.core.manage.StartActUserTaskManage;
import com.start.workflow.core.service.StartActBusinessService;
import com.start.workflow.core.service.StartActModelConfigService;
import com.start.workflow.entity.StartActBusinessEntity;
import com.start.workflow.entity.StartActModelConfig;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class StartGlobalUserTaskHandler extends StartBaseSingleton<StartGlobalUserTaskHandler> {


    private ExecutorService executorService;
    private static TaskService taskService;
    private static RepositoryService repositoryService;

    private static StartActBusinessService actBusinessService;

    private static StartActModelConfigService modelConfigService;


    private static StartActUserTaskManage startActUserTaskManage;


    /**
     * 调用初始化函数
     */
    @Override
    public void init() {
        executorService = Executors.newFixedThreadPool(5);
        taskService = SpringContextTools.getBean(TaskService.class);
        actBusinessService = SpringContextTools.getBean(StartActBusinessService.class);
        modelConfigService = SpringContextTools.getBean(StartActModelConfigService.class);
        startActUserTaskManage = SpringContextTools.getBean(StartActUserTaskManage.class);
        repositoryService = SpringContextTools.getBean(RepositoryService.class);
    }

    /**
     * 添加流程任务
     *
     * @param
     * @param task
     */
    public void addTask(TaskEntity task) {
        executorService.submit(new StartActTaskSycHandler(task));
    }


    public static StartGlobalUserTaskHandler getInstance() {
        return StartSingletonFactory.get(StartGlobalUserTaskHandler.class);
    }

    private static class StartActTaskSycHandler extends Thread {
        private final TaskEntity task;
        private StartActBusinessEntity actBusinessEntity;

        private List<StartBaseUser> users;
        private final static int max_trial_num = 50;
        private int current_num = 0;

        public StartActTaskSycHandler(TaskEntity task) {
            this.task = task;
        }

        @Override
        public void run() {
            TaskQuery taskQuery = taskService.createTaskQuery().taskId(task.getId());
            while (current_num <= max_trial_num) {
                current_num++;
                actBusinessEntity = actBusinessService.getOneByProcessInstanceId(task.getProcessInstanceId());
                if (actBusinessEntity == null || taskQuery.count() < 1) {
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
                initData();
                StartGlobalActTaskEventDispatcher.getInstance().onTaskCreateBefore(actBusinessEntity, task);
                handlerActBusiness();
                if (actBusinessEntity == null) return;
                StartGlobalActTaskEventDispatcher.getInstance().onTaskCreateAfter(actBusinessEntity, task);
                break;
            }
        }

        /**
         * 初始化查询数据
         */
        private void initData() {
            String processDefinitionId = task.getProcessDefinitionId();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
            if (modelConfigService.getActModelConfigCount(processDefinition.getDeploymentId()) < 1) return;
            StartActModelConfig assigneeConfigEntity = modelConfigService.getActModelConfig(processDefinition.getDeploymentId(), task.getTaskDefinitionKey(), StartActUserTaskConf.CANDIDATE_USER);
            if (assigneeConfigEntity == null) return;
            users = StartActCandidateManager.getInstance().loadCandidateUser(actBusinessEntity, assigneeConfigEntity);
        }

        private void handlerActBusiness() {
            if (users == null || users.isEmpty()) {
                return;
            }
            for (StartBaseUser user : users) {
                startActUserTaskManage.addUserTaskCandidateUser(task.getId(), user);
            }
        }

    }
}
